package com.situ.gcbs.server.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.situ.gcbs.server.dao.MemberDAO;
import com.situ.gcbs.server.model.Member;
import com.situ.gcbs.server.model.searchbean.MemberSearchBean;
import com.situ.gcbs.server.service.MemberService;
import com.situ.gcbs.server.util.PaginateInfo;
import org.jasypt.util.password.PasswordEncryptor;
import org.jasypt.util.password.StrongPasswordEncryptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;

/**
 * 功能：
 *
 * @author 千堆雪
 * @version 1.0.0
 * @since 2024/5/16
 * <p>
 * created by 千堆雪 on 2024/5/16 10:20, last modified by 千堆雪 on 2024/5/16 10:20
 */
@Service
public class MemberServiceImpl implements MemberService {
    private static final PasswordEncryptor PE = new StrongPasswordEncryptor();
    private MemberDAO memberDAO;

    @Autowired
    public void setMemberDAO(MemberDAO memberDAO) {
        this.memberDAO = memberDAO;
    }

    @Override
    public List<Member> findAll(PaginateInfo pi, MemberSearchBean msb) {
        try (Page<?> page = PageHelper.startPage(pi.getPageNo(), pi.getPageSize())) {
            List<Member> members = memberDAO.findAll(msb);

            PageInfo<Member> pageInfo = new PageInfo<>(members);

            pi.setPayload(pageInfo);

            return members;
        }
    }

    @Override
    public int deleteByIds(Integer[] ids, boolean force, boolean logic, Predicate<Member> predicate) {
        //如果是逻辑删除
        if (logic) {
            return logicDeleteByIds(ids, force, predicate);
        }

        //如果是物理删除
        if (force) {//如果是强制删除
            return memberDAO.deleteByIds(ids);
        }

        //非强制删除，则要进行断言
        List<Member> members = findByIds(ids);
        return members.stream().filter(predicate.negate()).mapToInt(this::delete).sum();
    }


    /**
     * 批量逻辑删除
     *
     * @param ids       要批量删除的id集合
     * @param force     是否强制删除
     * @param predicate 删除断言，满足条件的不删除
     * @return 成功删除的行数
     */
    private int logicDeleteByIds(Integer[] ids, boolean force, Predicate<Member> predicate) {
        Objects.requireNonNull(ids);

        Member member = new Member();
        member.setIsDel(true);

        //如果是强制删除
        if (force) {
            return memberDAO.patchByBatch(member, ids);
        }

        //非强制删除，则要进行断言
        List<Member> members = findByIds(ids);
        return members.stream().filter(predicate.negate()).mapToInt(this::logicDelete).sum();
    }

    /**
     * 逻辑删除
     *
     * @param member 会员实体
     * @return 成功删除的数量
     */
    private int logicDelete(Member member) {
        Objects.requireNonNull(member);
        return logicDeleteByIds(new Integer[]{member.getId()}, true, null);
    }

    @Override
    public boolean save(Member member) {
        Objects.requireNonNull(member);

        if (!StringUtils.hasText(member.getPhone())) {
            throw new IllegalArgumentException("会员手机号不可为空");
        }

        if (member.getPhone().length() != 11) {
            throw new IllegalArgumentException("会员手机号必须为11位");
        }

        if (!StringUtils.hasText(member.getPassword())) {
            member.setPassword(member.getPhone().substring(5));
        }

        member.setPassword(PE.encryptPassword(member.getPassword()));
        member.setCreateTime(LocalDateTime.now());
        return memberDAO.save(member) > 0;
    }

    @Override
    public boolean update(Member member) {
        if (StringUtils.hasText(member.getPassword())) {
            member.setPassword(PE.encryptPassword(member.getPassword()));
        }
        return memberDAO.update(member) > 0;
    }

    @Override
    public boolean patch(Member member) {
        if (StringUtils.hasText(member.getPassword())) {
            member.setPassword(PE.encryptPassword(member.getPassword()));
        }
        return memberDAO.patch(member) > 0;
    }
}
